package com.haois.mp.wechat.task;

import cn.zhouyafeng.itchat4j.api.WechatTools;
import com.haois.mp.database.commom.constant.Constants;
import com.haois.mp.database.commom.enums.MpTypeEnum;
import com.haois.mp.database.module.common.daomain.RemindDob;
import com.haois.mp.database.module.common.daomain.RemindMem;
import com.haois.mp.database.module.common.daomain.UserToken;
import com.haois.mp.database.module.common.service.IUserTokenService;
import com.haois.mp.database.module.offaccounts.service.RemindDobService;
import com.haois.mp.database.module.wxserver.util.TempMsgUtil;
import com.haois.mp.database.util.jx.DateUtil;
import com.haois.mp.wechat.common.BusinessRemind;
import me.chanjar.weixin.common.exception.WxErrorException;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * description
 *
 * @author RuiHaoZ on Hgits.cn
 * @date 2018/8/5 16:14
 */
@Component
public class BirthdayRemindTask {
    @Autowired
    private IUserTokenService iUserTokenService;
    @Autowired
    private RemindDobService remindDobService;
    @Value("${defined.wxmp.sys-openid}")
    private String sysOpenId;
    private Logger logger = LoggerFactory.getLogger(BirthdayRemindTask.class);
    Map<String, Object> params = new HashMap<>();

    /**
     * 每天早上提醒今日生日的用户
     */
    @Scheduled(cron = "0 20 8 ? * *")
    public Map<String, Object> remindBirthdayThisDay() {
        AtomicInteger pushSize = new AtomicInteger();
        logger.info("定时任务【每天早上提醒今日生日的用户】触发");
        List<RemindDob> remindDobs = remindDobService.findAll();
        List<RemindDob> thisDayRemindDobs = RemindDob.filter(remindDobs, RemindDob.DAY);
        Map<String, List<RemindDob>> map = handlerRemindDob(thisDayRemindDobs);
        map.forEach((k, v) -> {
            UserToken userToken = iUserTokenService.findByUserId(k, MpTypeEnum.OFFACCOUNTS.getType());
            if (userToken != null) {
                v.forEach(rm ->
                        this.remindUser(rm, userToken.getOpenId())
                );
            }
            pushSize.getAndIncrement();

        });
        logger.info("今日生日共发送模板推送[{}]次", pushSize);
        params.put("pushSize", String.valueOf(pushSize.get()));
        params.put("accordSize", thisDayRemindDobs.size());
        params.put("content", thisDayRemindDobs);
        return params;
    }

    /**
     * 每周第一天提醒本周生日的特别关心用户
     */
    @Scheduled(cron = "0 0 8 ? * SUN")
    public Map<String, Object> remindBirthdayThisWeek() {
        final int[] pushSize = {0};
        logger.info("定时任务【每周第一天提醒本周生日的特别关心用户】触发");
        List<RemindDob> remindDobs = remindDobService.findAll();
        List<RemindDob> thisWeekRemindDobs = RemindDob.filter(remindDobs, RemindDob.WEEK);
        Map<String, List<RemindDob>> map = handlerRemindDob(thisWeekRemindDobs);
        map.forEach((k, v) -> {
            UserToken userToken = iUserTokenService.findByUserId(k, MpTypeEnum.OFFACCOUNTS.getType());
            if (userToken != null) {
                v.stream().filter(rm -> rm.getVeryLike() == 1)
                        .forEach(rm -> {
                            rm.setName(rm.getName() + "(7日后生日)");
                            this.remindUser(rm, userToken.getOpenId());
                            pushSize[0]++;
                        });
            }
        });
        logger.info("7天后生日共发送模板推送[{}]次", pushSize[0]);
        params.put("pushSize", String.valueOf(pushSize[0]));
        params.put("accordSize", thisWeekRemindDobs.size());
        params.put("content", thisWeekRemindDobs);
        return params;
    }

    /**
     * 每月第一天提醒本月生日的用户
     */
    @Scheduled(cron = "0 8 10 1 * ?")
    public Map<String, Object> remindBirthdayThisMonth() {
        AtomicInteger pushSize = new AtomicInteger();
        logger.info("定时任务【每月第一天提醒本月生日的用户】触发");
        List<RemindDob> remindDobList = remindDobService.findAll();
        remindDobList = RemindDob.filter(remindDobList, RemindDob.MONTH);
        Map<String, List<RemindDob>> map = handlerRemindDob(remindDobList);
        pushSize = pushWeekAndMonthBirthday(map, "本月生日");
        logger.info("本月生日共发送模板推送[{}]次", pushSize);
        params.put("pushSize", String.valueOf(pushSize.intValue()));
        params.put("accordSize", remindDobList.size());
        params.put("content", remindDobList);
        return params;
    }

    @Scheduled(cron = "0 0 0 1 1 ?")
    public Map<String, Object> updateOnBirthday() {
        List<RemindDob> remindDobs = remindDobService.findAll();
        remindDobs.forEach(remindDob -> {
            remindDobService.update(remindDob);
        });
        params.put("pushSize", 1);
        params.put("accordSize", remindDobs.size());
        params.put("content", remindDobs);
        return params;
    }

    private void remindUser(RemindDob remindDob, String openId) {
        if (StringUtils.isBlank(openId)) {
            return;
        }
        Integer veryLike = remindDob.getVeryLike() == null ? 2 : remindDob.getVeryLike();
        remindDob.setOnAgeD();
        String[] tempDate = new String[]{
                remindDob.getName(),
                remindDob.getOnBirthday() != null ? DateUtil.getYMd(remindDob.getOnBirthday()) : "略",
                remindDob.getAgeD() != null ? String.valueOf(remindDob.getAgeD()) + "岁" : "略",
                veryLike == 2 ? "是/否" : (veryLike == 0 ? "否" : "是"),
                StringUtils.isNotBlank(remindDob.getUserContent()) ? remindDob.getUserContent() : remindDob.getContent()};
        try {
            BusinessRemind.remindByWx(tempDate, openId, TempMsgUtil.title_Remind_Bir, TempMsgUtil.temp_Remind_Bir,
                    TempMsgUtil.temp_Remind_Bir_Color);
            try {
                StringBuffer sbContent = new StringBuffer();
                String name = StringUtils.isNotBlank(remindDob.getNickName()) ? remindDob.getNickName() : remindDob.getName();
                sbContent.append("今天是").append("\n")
                        .append(name).append("的生日").append("\n")
                        .append("祝您生日快乐");
                String content = StringUtils.isNotBlank(remindDob.getGroupContent())
                        ? remindDob.getGroupContent() : sbContent.toString();

                String groupId = "";
                if (StringUtils.isNotBlank(remindDob.getGroupList())) {
                    String[] groupList = remindDob.getGroupList().split("/");
                    for (String s : groupList) {
                        groupId = WechatTools.getGroupUserNameByNickName(s);
                        if (StringUtils.isNotBlank(groupId)) {
                            logger.info("目标群的ID为：{}，发送成功", groupId);
                            WechatTools.sendMsgByUserName(content, groupId);
                        } else {
                            logger.info("目标群的ID未找到");
                        }
                    }
                }
            } catch (Exception e) {
                logger.error("消息发送给群[{}]出现错误");
            }
        } catch (
                WxErrorException e) {
            e.printStackTrace();
        }

    }


    private Map<String, List<RemindDob>> handlerRemindDob(List<RemindDob> remindDobs) {
        Map<String, List<RemindDob>> map = new HashMap<>();
        remindDobs.forEach(remindDob -> {
            List<RemindMem> members = remindDobService.findByBirId(remindDob.getId());
            members.forEach(member -> {
                List<RemindDob> rm = new ArrayList<>();
                if (map.containsKey(member.getMemberNum())) {
                    rm = map.get(member.getMemberNum());
                }

                RemindDob rd = new RemindDob(remindDob);
                rd.setGroupList(member.getGroupList());
                rd.setNickName(member.getNickName());
                rd.setGroupContent(member.getGroupContent());
                rd.setUserContent(member.getUserContent());
                rm.add(rd);

                map.put(member.getMemberNum(), rm);
            });
        });
        return map;
    }

    private AtomicInteger pushWeekAndMonthBirthday(Map<String, List<RemindDob>> map, String name) {
        AtomicInteger pushSize = new AtomicInteger();
        RemindDob remindDob = new RemindDob();
        remindDob.setName(name);
        map.forEach((k, v) -> {
            UserToken userToken = iUserTokenService.findByUserId(k, MpTypeEnum.OFFACCOUNTS.getType());
            if (userToken != null) {
                StringBuffer content = new StringBuffer("");
                v.forEach(rm -> {
                    content.append(rm.getName()).append("：")
                            .append(DateUtil.getYMd(rm.getOnBirthday())).append("\n");
                });
                remindDob.setContent(content.toString());
                pushSize.getAndIncrement();
                this.remindUser(remindDob, userToken.getOpenId());
            }
        });
        return pushSize;
    }
}
